﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using Sunny.UI;
using welding.Controller;
using welding.Model;
using Newtonsoft.Json;

namespace welding
{
    public partial class mainForm : Form
    {
        private int access_right;
        bool isBypass = false;
        private string p;
        int iSumPrint = 0;


        //本班次加工完成数量
        private int finishedQuantity;
        //本班次合格数量
        private int okQuantity;
        //本班次不合格数量
        private int ngQuantity;
        //本班次返工数量
        private int reQuantity;
        //开班时间
        public DateTime ShiftStartTime = Convert.ToDateTime("08:00:00");
        //时间同步标志
        string strRefreshTimeDate = string.Empty;

        XMLHelper xmlHelper = new XMLHelper();
        private string user_name;
        private string user_id;
        public string SystemConfigPwd { get; private set; }

        private string device_name;

        private Device m_device; //设备实例

        private int barcode_num = 0;
        private string barcode_names = string.Empty;
        private int station_num = 0;
        private bool bprint_barcode = false;
        //计划加工数量
        private int planQty = 0;
        //确认加工结果窗口是否打开？ConfirmResult Form是否打开？
        private bool isConfirmResultShowing = false;

        ConfirmResult confirmResult;

        //设备状态 等待加工=0，等待回复=1，加工中=2
        int MachineStatusA = 0;
        int MachineStatusB = 0;
        //等待UCOM回复计时
        int WaitingTimeA = 0;
        int WaitingTimeB = 0;
        //存贮当前加工的零部件的条码
        string m_strBarcode = string.Empty;
        string m_strWorkOrder = string.Empty;
        string strBarcodeA1 = string.Empty;
        string strBarcodeA2 = string.Empty;
        string strBarcodeA3 = string.Empty;
        string strBarcodeB1 = string.Empty;
        string strBarcodeB2 = string.Empty;
        string strSerialNumA = string.Empty;
        string strSerialNumB = string.Empty;
        string strErrorMes = string.Empty;
        string strInfo = string.Empty;
        string strConfig = string.Empty;
        //加工时间
        string StartTimeA = string.Empty;
        string EndTimeA = string.Empty;
        string StartTimeB = string.Empty;
        string EndTimeB = string.Empty;

        bool bLoadMat = false;
        bool bTabAworking = false;
        bool bTabBworking = false;

        bool isSilent = false;      //三色灯是静音模式吗？

        string strTabA = "A";
        string strTabB = "B";
        //工位正在加工返回字符信息
        string strStationWorking = "strStationWorking";
        //加工完成字符串
        //string strOver = "Over";
        const string strOKA = "OverA";
        const string strNGA = "NGA";
        string strOKB = "OverB";
        string strNGB = "NGB";
        const string strCancelA = "CancelA";
        string strCancelB = "CancelB";
        const string strRepairA = "RepairA";
        const string strRepairB = "RepairB";
        const string strPrint = "print";
        bool bToPrint = false;

        //参数数量
        int iParameterNum = 0;
        string strMat1 = "M1";
        string strMat2 = "M2";
        login lgn = new login();
        bool bLoginForm = false;
        string NoParameter = "原料不足请上料";

        //有在加工件？搪塑工位可以没有这个标志位
        bool isMachineWorking = false;
        //
        Color flashInformationColor = new Color();

        string[] m_suspendReasons;
        string[] m_suspendSolutions;

        string m_materialNumber = "1";

        public mainForm()
        {
            InitializeComponent();
        }
        public mainForm(int access_right, string user_name, string user_id, string device_name, int barcode_num, string barcode_names, int station_num, bool bprint_barcode, int planQty, List<ProductionDataClass> productionDatas, DateTime ShiftStart)
        {
            InitializeComponent();
            // TODO: Complete member initialization
            this.access_right = access_right;
            this.user_name = user_name;
            this.user_id = user_id;
            this.planQty = planQty;
            this.finishedQuantity = finishedQuantity;
            this.okQuantity = okQuantity;
            this.ShiftStartTime = ShiftStart;
            ShowProductQuantity(productionDatas);

            this.barcode_num = 1;
            this.station_num = 1;
            this.bprint_barcode = true;

            alarmLoopCounter = LoopAlarmDuration * 1000 / alarmTimer.Interval;

            LoadParameters();

            vmTcpIpUcom.LoadSettings();

            vmTcpPrinter.LoadSettings();
            vmModbusTcpMaster1.LoadSettings();

            vmTcpPrinter.Start();

            vmTcpIpUcom.Start();

            vmModbusTcpMaster1.Start();

            //启动timer
            mainTimer.Start();
            confirmResultTimer.Start();
            lblUserName.Text = user_name;
            lblUser.Text = user_id;

            uiLabelInfo.Text = "系统启动，请扫描骨架条码。";


            Thread.Sleep(500);

            InitDevice();
        }

        int LoopAlarmDuration = 180;
        private void LoadParameters()
        {
            string strDeviceCode = xmlHelper.ReadXml(cvs.DP.SYSTEM_CONFIG_FILE, "DEVICE_CODE");

            // 按归顺序扫描
            string strScanByOrder = xmlHelper.ReadXml(cvs.DP.SYSTEM_CONFIG_FILE, "SCAN_BY_ORDER");
            if (strScanByOrder == "0") uiCheckBoxScanOrder.Checked = false;
            else
                uiCheckBoxScanOrder.Checked = true;

            string strSystemConfigPwd = xmlHelper.ReadXml(cvs.DP.SYSTEM_CONFIG_FILE, "SYSTEM_CONFIG_PWD");
            BypassConfigPwd = xmlHelper.ReadXml(cvs.DP.SYSTEM_CONFIG_FILE, "BYPASS_CONFIG_PWD");
            m_bBypassPlc = xmlHelper.ReadXml(cvs.DP.SYSTEM_CONFIG_FILE, "BYPASS") == "1" ? true : false;
            if (m_bBypassPlc)
            {
                btnBypassPlc.BackColor = Color.Yellow;
                btnBypassPlc.Text = "连接设备";
            }
            else
            {
                btnBypassPlc.BackColor = Color.LightGreen;
                btnBypassPlc.Text = "设备通讯";
            }

            string strAlarmDuration = xmlHelper.ReadXml(cvs.DP.SYSTEM_CONFIG_FILE, "ALARM_DURATION");
            bool verify = false;
            verify = int.TryParse(strAlarmDuration, out LoopAlarmDuration);

            if (!verify) LoopAlarmDuration = 180;

            SystemConfigPwd = strSystemConfigPwd;
            device_name = strDeviceCode;
            lblDeviceName.Text = strDeviceCode;
            tbDeviceName.Text = strDeviceCode;

        }

        private void mainTimer_Tick(object sender, EventArgs e)
        {
            if (DateTime.Now.Hour >= 8 && DateTime.Now.Hour <= 20)
                lblShift.Text = "早班";
            else
                lblShift.Text = "晚班";

            //监控停机时间
            CheckLogTime();
            //if (isBypass == true) return;
            if (MachineStatusA == 1)
            {
                if (WaitingTimeA <= 20)
                {
                    WaitingTimeA++;
                    if (WaitingTimeA >= 20)
                    {
                        //超时未回复报警
                    }
                }
            }

            if (MachineStatusB == 1)
            {
                if (WaitingTimeB <= 20)
                {
                    WaitingTimeB++;
                    if (WaitingTimeB >= 20)
                    {
                        //超时未回复报警
                    }
                }
            }
            //HandleSerialPort();
            HandleTcpIp();

            HandleModBus();

            //请求报产等产品加工数据
            RequestProductionData();
        }
        int m_ModBusTestStep = 0;
        private void HandleModBus()
        {
            if (m_bBypassPlc) return;

            string value = "";

            switch (m_ModBusTestStep)
            {
                case cvs.MODBUS.STEP_IDLE:
                    break;
                case cvs.MODBUS.STEP_SENT_RESET:        // 等待复位完成信号
                    // ADDR100==1? 复位完成？
                    value = vmModbusTcpMaster1.Get(1, "ResetDone100");
                    if (value == "1")
                    {
                        vmModbusTcpMaster1.Set(1, "Reset000", "0");
                        vmModbusTcpMaster1.Set(1, "ResetDone100", "0");
                        // 发送启动信号
                        m_ModBusTestStep = cvs.MODBUS.STEP_SENT_START;

                        // 向电测设备发送启动消息
                        vmModbusTcpMaster1.Set(1, "Start020", "1");

                        DisplayInformation("启动信号已经发送", Color.LightGreen);
                    }

                    break;
                case cvs.MODBUS.STEP_SENT_START:
                    // ADDR101==1? 正在检测？
                    value = vmModbusTcpMaster1.Get(1, "Testing101");
                    if (value == "1")
                    {
                        vmModbusTcpMaster1.Set(1, "Start020", "0");
                        vmModbusTcpMaster1.Set(1, "Testing101", "0");
                        m_ModBusTestStep = cvs.MODBUS.STEP_TESTING;
                        DisplayInformation("正在检测......", Color.LightGreen);
                    }
                    else
                    {
                        // 再次发动启动信号
                        vmModbusTcpMaster1.Set(1, "Start020", "1");
                    }
                    break;
                case cvs.MODBUS.STEP_TESTING:
                    // ADDR21==1? 检测完成？
                    value = vmModbusTcpMaster1.Get(1, "TestOver021");
                    if (value == "1")
                    {
                        vmModbusTcpMaster1.Set(1, "TestOver021", "0");
                        m_ModBusTestStep = cvs.MODBUS.STEP_TEST_OVER;
                        DisplayInformation("检测完毕", Color.LightGreen);

                        // 保存数据 ADDR94
                        string testResult = vmModbusTcpMaster1.Get(1, "TestResult094");
                        switch (testResult)
                        {
                            case "85":
                                testResult = "1";      // OK
                                break;
                            case "255":
                                testResult = "4";      // 超时
                                break;
                            default:
                                testResult = "2";      // NG
                                break;
                        }
                        Checkout(int.Parse(testResult));
                        //SaveTestData();

                        m_ModBusTestStep = cvs.MODBUS.STEP_IDLE;

                        //ResetScanningTextBox();
                        EnableScanningTextBox(true);
                    }
                    break;
            }
        }

        private void SaveTestData()
        {
            string testResult = vmModbusTcpMaster1.Get(1, "TestResult094");

            string _strSendToUcom = "SAVE_ELECTEST," + DateTime.Now.ToString("HHmmss") + "," + device_name + ",";
            _strSendToUcom += user_id + ",";
            _strSendToUcom += uiTextBoxScan.Text + ",";
            //         _strSendToUcom += "MATERIAL1:" + uiTextBoxArm.Text + ";" + "MATERIAL2:" + uiTextBoxWire.Text + ",";
            _strSendToUcom += testResult;
            vmTcpIpUcom.Set(_strSendToUcom);
        }

        //请求报产等产品加工数据计数器
        int requestProductionDataCounter = 0;
        /// <summary>
        /// 发送到服务器：请求报产等产品加工数据:包括合格/不合格/返修/报产/完成数量等等
        /// 
        /// </summary>
        private void RequestProductionData()
        {
            requestProductionDataCounter++;
            //5分钟发送一次请求
            if (mainTimer.Interval * requestProductionDataCounter >= 300000)
            {
                requestProductionDataCounter = 0;
                //发送请求命令到服务器
                string _cmd = "REQUESTPRODUCTIONDATA,";
                _cmd += DateTime.Now.ToString("HHmmss") + ",";
                _cmd += device_name;
                vmTcpIpUcom.Set(_cmd);
            }
        }


        //存贮加工数据，加工工作参数


        private void PrintBarcode(PrintBarcodeData printBarcodeData)
        {
            string str = string.Empty;
            //string strChangan = "CHANG AN";

            if (printBarcodeData.barcode == string.Empty) return;

            //只打印流水，将配置去掉
            string flow = printBarcodeData.barcode
                .Replace("-", "")
                .Replace(printBarcodeData.config.Replace("-", ""), "");

            //str = @"^XA^A@,N,50,50,E:ARI000_^LH10,20^BY2,2.0";
            //str += @"^FO10,2^A0N,20,25^A@N,28,28,E:ARI000^FH\^CI0^FD" + printBarcodeData.config + "^FS";
            //str += @"^FO10,50^A0N,20,35^A@N,28,28,E:ARI000^FH\^CI0^FD" + flow + "^FS";
            //str += @"^BY2,2.0^FO210,5^BXN,4,200^FD" + printBarcodeData.barcode + "^FS^XZ";     //二维码打印

            str = @"^XA^CFA,40^FO30,40^FD" + printBarcodeData.configPrefix + "^FS";          // HA5H
            str += @"^CFA,30^FO220,40^FD佛吉亚（中国）投资有限公司^FS";
            str += @"^CFA,20^FO280,90^FDVendor Code: 153390^FS";

            str += @"^CFF,30^FO30,120^FD" + printBarcodeData.config + "^FS";
            str += @"^FO30,180^FD" + printBarcodeData.name + "^FS";
            str += @"^FO30,240^FD生产日期: " + printBarcodeData.flow + "^FS";

            str += @"^FO350,120^BQN,2,6^FDMM,A" + printBarcodeData.barcode + "^FS";        // QR
            str += @"^XZ";

            vmTcpPrinter.Set(str);
        }
        private void Ip2PrintBarcode(PrintBarcodeData printBarcodeData)
        {
            string str = string.Empty;
            string strChangan = "CHANG AN";

            if (printBarcodeData.barcode == string.Empty) return;
            str = @"^XA^A@,N,50,50,E:ARI000_^LH10,20^BY2,2.0^FO55,50^BCN,57,N,N,N,A^FD" + printBarcodeData.barcode
                + "^FS^LH10,20^FO55,180^BCN,57,N,N,N,A^FD" + printBarcodeData.barcode +
                @"^FS^FO55,5^A0N,30,28^A@N,28,28,E:ARI000^FH\^CI0^FD" + strChangan +
                @"^FS^CI0^FO215,5^A0N,30,28^A@N,28,28,E:ARI001^FH\^CI0^FD" + printBarcodeData.date +
                @"^FS^CI0^FO345,5^A0N,30,28^A@N,28,28,E:ARI001^FH\^CI0^FD" + printBarcodeData.config + "^FS" +
@"^CW1,E:SIMSUN.TTF" +
@"^SEE:GB18030.DAT^CI26" +
                @"^FO525,5^A1N,20,20^FD" + printBarcodeData.ICA2CfgChn +

             @"^FS^CI0^FO65,120^A0N,20,25^A@N,28,28,E:ARI000^FH\^CI0^FD" + printBarcodeData.barcode +
                @"^FS^^FO65,250^A0N,20,25^A@N,28,28,E:ARI000^FH\^CI0^FD" + printBarcodeData.barcode + "^FS^XZ";


            vmTcpPrinter.Set(str);
        }
        private void HandleTcpIp()
        {
            string strTcpIpGet = vmTcpIpUcom.Get();
            if (strTcpIpGet != "")
            {
                SaveLogToFile(device_name, strTcpIpGet, 1);
                string[] strTcpIps = strTcpIpGet.Split(',');

                CommunicationClass communication = DeserializeCommunication(strTcpIpGet);

                if (communication == null) // 不是JASON格式的命令
                {
                    switch (strTcpIps[0])
                    {
                        case "DEVICE":
                            HandleDevice(strTcpIps);
                            break;
                        case "VALIDATE_ELECTEST":
                            HandleValidateElecTest(strTcpIps);
                            break;
                        case "SAVE_ELECTEST":
                            HandleSaveElecTest(strTcpIps);
                            break;
                        case "REPRINTPLS":
                            HandleReprintPls(strTcpIps);
                            break;
                        case "CONTPRINTPLS": //连续打印
                            HandleContPrintPls(strTcpIps);
                            break;
                        case "REQUESTPRODUCTIONDATA":  //请求生产加工数据
                            HandleRequestProductionData(strTcpIps);
                            break;
                    }
                }
                else // 是JASON格式的命令
                {
                    switch (communication.cmd)
                    {
                        case "GetWorkOrder": // 读取工单信息，工单中的配置，配置使用的物料列表，工单的数量等
                            HandleGetWorkOrder(strTcpIpGet);
                            break;
                        case "CHECKIN":
                            HandleCheckin(strTcpIpGet);
                            break;
                        case "CHECKOUT":
                            HandleCheckout(strTcpIpGet);
                            break;
                        case "REPRINT_BARCODE":                 // 补打一个旧的条码返回命令
                            HandleReprintBarcode(strTcpIpGet);
                            break;
                        case "PRINT_M":                 // 连续打印多个条码返回命令
                            HandlePrintM(strTcpIpGet);
                            break;
                        case "DEVICE":
                            HandleDevice(strTcpIpGet);
                            break;
                    }
                }

                if (strErrorMes.Length > 0)
                {
                    DisplayWarningInformation(strErrorMes, Color.Red);
                    strErrorMes = "";
                }
            }
        }

        private void HandlePrintM(string rcv)
        {
            ReprintBarcodeController controller = new ReprintBarcodeController(rcv);

            if (controller.ReprintBarcodeResponse.status == "OK")
            {
                PrintCustomerBarcode(controller.ReprintBarcodeResponse.partData);
            }
            else
            {
                DisplayInformation(controller.ReprintBarcodeResponse.message, Color.Red);
            }
        }

        /// <summary>
        /// 补打一个旧的条码返回命令
        /// </summary>
        /// <param name="strTcpIpGet"></param>
        private void HandleReprintBarcode(string rcv)
        {
            ReprintBarcodeController controller = new ReprintBarcodeController(rcv);

            if (controller.ReprintBarcodeResponse.status == "OK")
            {
                PrintCustomerBarcode(controller.ReprintBarcodeResponse.partData);
            }
            else
            {
                DisplayInformation(controller.ReprintBarcodeResponse.message, Color.Red);
            }
        }

        private void HandleCheckout(string rcv)
        {
            CheckoutController controller = new CheckoutController(rcv);

            if (controller.CheckoutResponse.status == "OK")
            {
                if (controller.CheckoutResponse.cmdTime == m_serialNo)
                {
                    DisplayInformation(controller.CheckoutResponse.workOrder + " 加工完成", Color.LightGreen);

                    if (controller.CheckoutResponse.cmd == "CHECKOUT")
                    {
                        if (toCreateCustomerBarcode == 1)
                        {
                            // 从 part 数据中获取打印信息
                            if (controller.CheckoutResponse.partData != null)
                            {
                                PrintCustomerBarcode(controller.CheckoutResponse.partData);
                            }
                        }
                    }
                }
            }
            else
            {
                DisplayInformation(controller.CheckoutResponse.message, Color.Red);
            }

            ShowProductQuantity(controller.CheckoutResponse.productions);

            MachineStatusA = 0;
            //m_scanInProcess = false;        // 正在扫描物料？
            bTabAworking = false;
            m_strBarcode = "";
            m_strWorkOrder = "";
            uiLabelConfig.Text = string.Empty;

        }

        private void PrintCustomerBarcode(PartDataClass partData)
        {
            for (int i = 0; i < partData.customerBarcodes.Count; i++)
            {
                string str = @"^XA";
                str += @"^A@N,30,30,E:ARI000^FH^CI0^FO230,70^FD" + partData.CustomerPartId + "^FS";                // 16290287-00
                str += @"^A@N,28,28,E:ARI000^FH^CI0^FO230,110^FD" + partData.partId + "^FS";                // HA5H-5305100-00YBM
                str += @"^CW1,E:SIMSUN.TTF^SEE:GB18030.DAT^CI26";
                str += @"^FO230,150^A1N,26,26^FD" + partData.partName + "^FS";   // 副仪表板本体总成-砂金米
                str += @"^A@N,30,30,E:ARI000^FH^CI0^FO230,190^FD" + partData.customerBarcodes[i] + "^FS";        // CUSTOMER BARCODE
                str += @"^FO70,60^BQN,2,7^FDMM,A" + partData.customerBarcodes[i] + "^FS";        // QR
                str += @"^XZ";

                vmTcpPrinter.Set(str);
                Thread.Sleep(100);
            }
            //str += @"^A@,N,50,50,E:ARI000_^LH10,20^BY2,2.0^FO100,5^BCN,57,N,N,N,A^FD" + partData.customerBarcode + "^FS";
            //str += "^CFA,30^FO100,70^FD" + "*" + partData.customerBarcode + "*^FS";
            //str += @"^CW1,E:SIMSUN.TTF^SEE:GB18030.DAT^CI26";
            //str += @"^FO100,105^A1N,24,24^FD" + "零件名称:" + partData.partName + "^FS";
            //str += @"^FO100,140^A1N,24,24^FD" + "零件编号:" + partData.partId + "^FS";
            //str += "^XZ";

            //str = @"^XA^CFA,40^FO30,40^FD" + printBarcodeData.configPrefix + "^FS";          // HA5H
            //str += @"^CFA,30^FO220,40^FD佛吉亚（中国）投资有限公司^FS";
            //str += @"^CFA,20^FO280,90^FDVendor Code: 153390^FS";
        }


        private void HandleCheckin(string strTcpIpGet)
        {
            CheckinController controller = new CheckinController(strTcpIpGet);

            if (controller.CheckinResponse.status == "NOK")
            {
                DisplayInformation(controller.CheckinResponse.message, Color.Red);
                m_strBarcode = "";
                m_strWorkOrder = "";
                return;
            }
            else
            {
                DisplayInformation("正在加工", Color.LightGreen);
            }

            toCreateCustomerBarcode = controller.CheckinResponse.toCreateCustomerBarcode;

            // 弹出 选择加工结果 窗口
            m_startTimeA = DateTime.Now.ToString();

            MachineStatusA = 2;             //正在加工，1-等待回复，0-空闲
            toOpenConfirmResult = true;

        }

        private void HandleGetWorkOrder(string response)
        {
            WorkOrderController controller = new WorkOrderController(response);

            if (controller.WorkOrderResponse.status == "NOK")
            {
                DisplayInformation(controller.WorkOrderResponse.message, Color.Red);
                m_strBarcode = "";
                m_strWorkOrder = "";
                return;
            }
            else
            {
                DisplayInformation("请扫描物料条码", Color.LightGreen);
            }

            //lblWorkOrder.Text = controller.WorkOrderResponse.workOrderData.workOrder;

            //if (m_strBarcode != string.Empty) lblWorkOrder.Text += " 正在进行返工操作";

            //// 进入扫描状态，不允许进行返工操作
            //m_scanInProcess = true;

            // 设置已经收到来自UCOM发回的物料列表
            //m_isMatListOnConfigReceived = true;

            uiDataGridViewSparePart.Rows.Clear();

            // 骨架条码的配置信息加入到列表中
            //var m2 = new ProductConfigWithItemContent();
            //m2.content = controller.WorkOrderResponse.workOrderData.config;
            //m2.scan = m_strBarcode;
            //m2.item = "";

            //List<ProductConfigWithItemContent> m3 = new List<ProductConfigWithItemContent>();
            //m3.Add(m2);


            //if (controller.WorkOrderResponse.productConfigs != null &&
            //    controller.WorkOrderResponse.productConfigs.Count != 0)
            //{
            m_matListOnConfigCount = controller.WorkOrderResponse.productConfigs.Count;

            // 所需物料的信息加入到列表中
            //m_productConfigWithItemContent = m3.Concat(controller.WorkOrderResponse.productConfigs).ToList();
            m_productConfigWithItemContent = controller.WorkOrderResponse.productConfigs.ToList();
            //}
            //else
            //{
            //    m_productConfigWithItemContent = m3;
            //}

            //UI显示数据
            for (int i = 0; i < m_productConfigWithItemContent.Count; i++)
            {
                uiDataGridViewSparePart.Rows.Add();
                uiDataGridViewSparePart.Rows[i].Cells["item"].Value = m_productConfigWithItemContent[i].item;
                uiDataGridViewSparePart.Rows[i].Cells["content"].Value = m_productConfigWithItemContent[i].content;
                uiDataGridViewSparePart.Rows[i].Cells["scan"].Value = m_productConfigWithItemContent[i].scan;
            }

            m_config = controller.WorkOrderResponse.workOrderData.config;

            uiTextBoxScan.Focus();
            uiTextBoxScan.Text = string.Empty;
        }

        private CommunicationClass DeserializeCommunication(string str)
        {
            try
            {
                return JsonConvert.DeserializeObject<CommunicationClass>(str);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }

        /// <summary>
        /// 请求生产加工数据
        /// </summary>
        /// <param name="strTcpIps"></param>
        private void HandleRequestProductionData(string[] strTcpIps)
        {
            //整理数据: Cmd,Sn,deviceid,result:OK/NOK,ERROR MSG,CONFIG:FINISHED:OK:NOK:REPAIR:REPORTYIELD

            if (strTcpIps.Length < 6) return;

            Production production = new Production(strTcpIps[5]);

            List<ProductionDataClass> productionDatas = production.productionDatas;

            //UI显示数据



            ShowProductQuantity(productionDatas);



        }
        private void HandleContPrintPls(string[] strTcpIps)
        {
            // REPRINT, TIME, DEVICEID,USERID, CONFIG, OK / NOK, ERROR MSG / barcode list, production data
            if (strTcpIps.Length < 7)
            {
                DisplayInformation("UCOM返回格式错误", Color.Red);
                return;
            }
            string _deviceId = strTcpIps[2];
            string _config = strTcpIps[4];
            string _result = strTcpIps[5];
            string _errMsg = strTcpIps[6];
            string[] _barcodes = strTcpIps[6].Split(';');

            if (_result != "OK")
            {
                DisplayInformation(_errMsg, Color.Red);
                return;
            }
            foreach (string _barcode in _barcodes)
            {
                if (_barcode.Trim() == string.Empty) continue;

                PrintBarcodeData _printBarcodeData = new PrintBarcodeData();
                _printBarcodeData.barcode = _barcode;
                _printBarcodeData.config = _config;
                PrintBarcode(_printBarcodeData);
            }
            if (strTcpIps.Length > 7)
            {
                ShowProductQuantity(FormatProductionData(strTcpIps[7]));
            }
        }
        private void HandleReprintPls(string[] strTcpIps)
        {
            // REPRINT, TIME, DEVICEID, barcode, CONFIG, OK / NOK, ERROR MSG, production data
            if (strTcpIps.Length < 7)
            {
                DisplayInformation("UCOM返回格式错误", Color.Red);
                return;
            }
            string _deviceId = strTcpIps[2];
            string _barcode = strTcpIps[3];
            string _config = strTcpIps[4];
            string _result = strTcpIps[5];
            string _errMsg = strTcpIps[6];

            if (_result != "OK")
            {
                DisplayInformation(_errMsg, Color.Red);
                return;
            }
            PrintBarcodeData _printBarcodeData = new PrintBarcodeData();
            _printBarcodeData.barcode = _barcode;
            _printBarcodeData.config = _config;
            PrintBarcode(_printBarcodeData);
        }
        /// <summary>
        /// 验证配置与物料是否匹配
        /// </summary>
        /// <param name="strTcpIps"></param>
        private void HandleValidateElecTest(string[] strTcpIps)
        {
            isMachineWorking = false;
            strBarcodeA1 = "";
            strBarcodeA2 = "";

            //VALIDATE_ELECTEST, TIME, DEVICE,USER_ID, CONFIG, MATONE;MATTWO,OK/ONK,BARCODE/ERR MSG, CONFIG:FINISHEDQTY:OKQTY:NGQTY:REPAIREDQTY
            if (strTcpIps.Length < 8)
            {
                DisplayInformation("返回信息格式错误", Color.Red);
                return;
            }

            if (strTcpIps[6] == "OK")       // 条码验证成功
            {
                SendReset();
            }
            else
            {
                EnableScanningTextBox(true);

                DisplayInformation(strTcpIps[7], Color.Red);
            }
        }
        private void SendReset()
        {
            m_ModBusTestStep = cvs.MODBUS.STEP_SENT_RESET;

            // 向电测设备发送复位消息
            vmModbusTcpMaster1.Set(1, "Reset000", "1");

            DisplayInformation("条码验证成功，复位信号已经发送", Color.LightGreen);

        }
        private void HandleSaveElecTest(string[] strTcpIps)
        {
            isMachineWorking = false;
            strBarcodeA1 = "";
            strBarcodeA2 = "";

            // SAVE_ELECTEST, TIME, DEVICE, USER_ID, CONFIG,
            // MATONE;MATTWO, OK/ONK, BARCODE/ERR MSG, CONFIG:FINISHEDQTY:OKQTY:NGQTY:REPAIREDQTY,
            // vendorCode;config;product name;flow (153390;HA5H-5305030;副仪表盘后安装支架总成;2403280001)

            if (strTcpIps.Length < 10)
            {
                DisplayInformation("返回信息格式错误", Color.Red);
                return;
            }
            if (strTcpIps[7] == "OK" || strTcpIps[7] == "NG")
            { // OK / NG 都要更新生产加工数据列表
                PrintBarcodeData _printBarcodeData = new PrintBarcodeData();
                _printBarcodeData.barcode = strTcpIps[8];
                _printBarcodeData.config = strTcpIps[4];
                string[] items = strTcpIps[10].Split(';');
                if (items.Length >= 4)
                {
                    _printBarcodeData.vendorCode = items[0];
                    _printBarcodeData.configPrefix = items[1].Split('-')[0];
                    _printBarcodeData.name = items[2];
                    _printBarcodeData.flow = items[3];
                }
                if (strTcpIps[7] == "OK")
                {
                    PrintBarcode(_printBarcodeData);
                    DisplayInformation(_printBarcodeData.barcode + " 加工成功", Color.LightGreen);
                }
                else
                {
                    DisplayInformation(_printBarcodeData.barcode + " 加工失败", Color.Red);
                }
                ResetScanningTextBox();

                List<ProductionDataClass> productionDatas = new List<ProductionDataClass>();
                string[] _data = strTcpIps[9].Split(';');
                foreach (string _str in _data)
                {
                    ProductionDataClass _productionData = new ProductionDataClass();
                    if ((_str != null) && (_str != string.Empty))
                    {
                        //config, finishedQty, okQty, ngQty, repairedQty, report Yield
                        string[] _item = _str.Split(':');
                        if (_item.Length >= 6)
                        {
                            _productionData.config = _item[0];

                            bool _v = int.TryParse(_item[1], out _productionData.finishedQty);
                            _v = int.TryParse(_item[2], out _productionData.okQty);
                            _v = int.TryParse(_item[3], out _productionData.ngQty);
                            _v = int.TryParse(_item[4], out _productionData.repairedQty);
                            _v = int.TryParse(_item[5], out _productionData.reportYield);
                            productionDatas.Add(_productionData);
                        }
                    }
                }
                ShowProductQuantity(productionDatas);
            }
            else
            {
                DisplayInformation(strTcpIps[8], Color.Red);
            }
        }
        private List<ProductionDataClass> FormatProductionData(string data)
        {
            List<ProductionDataClass> productionDatas = new List<ProductionDataClass>();
            string[] _data = data.Split(';');
            foreach (string _str in _data)
            {
                ProductionDataClass _productionData = new ProductionDataClass();
                if ((_str != null) && (_str != string.Empty))
                {
                    //config, finishedQty, okQty, ngQty, repairedQty, report Yield
                    string[] _item = _str.Split(':');
                    if (_item.Length >= 6)
                    {
                        _productionData.config = _item[0];

                        bool _v = int.TryParse(_item[1], out _productionData.finishedQty);
                        _v = int.TryParse(_item[2], out _productionData.okQty);
                        _v = int.TryParse(_item[3], out _productionData.ngQty);
                        _v = int.TryParse(_item[4], out _productionData.repairedQty);
                        _v = int.TryParse(_item[5], out _productionData.reportYield);
                        productionDatas.Add(_productionData);
                    }
                }
            }
            return productionDatas;
        }
        private void HandleSerialPort()
        {
            //如果设备处于停机状态，就报警然后退出
            if (m_device.DeviceInfomation.DeviceState != cvs.DEVICE_STATE.NORMAL)
            {
                DisplayInformation("设备处于停机状态，请取消停机。", Color.Red);
                return;
            }

            // 收到扫描枪从串口发来的数据

            //if (strScanner != string.Empty)
            {
                //如果设备处于停机状态，就报警然后退出
                if (m_device.DeviceInfomation.DeviceState != cvs.DEVICE_STATE.NORMAL)
                {
                    DisplayInformation("设备处于停机状态，请取消停机。", Color.Red);
                    return;
                }

                alarmLoopCounter = LoopAlarmDuration * 1000 / alarmTimer.Interval;
                isAlarmLoopWorking = false;

                string strTcpIpSend = string.Empty;

                //HandlePrint(strScanner);

            }
        }
        private void btnSaveSysConf_Click(object sender, EventArgs e)
        {
            vmTcpIpUcom.SaveSettings();
            vmTcpPrinter.SaveSettings();
        }
        static public void SaveLogToFile(string station, string strLog, int cnt)
        {
            DateTime dtCurrentTime = DateTime.Now;
            string strFileName = dtCurrentTime.Year.ToString("D2") + dtCurrentTime.Month.ToString("D2") + dtCurrentTime.Day.ToString("D2");
            if (cnt == -1)
                strFileName = cvs.DP.LOG_DIRECTORY + "\\ERR-" + strFileName + ".txt";
            else
                strFileName = cvs.DP.LOG_DIRECTORY + station + "-" + strFileName + ".txt";
            try
            {
                StreamWriter fsw = new StreamWriter(strFileName, true);
                string str = dtCurrentTime.Hour.ToString("D2") + dtCurrentTime.Minute.ToString("D2") + dtCurrentTime.Second.ToString("D2");
                fsw.Write(str + "\t" + strLog + "\r\n");
                fsw.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        private void btnInit_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show("初始化会导致在加工数据丢失，请确认是否继续？", "警告", MessageBoxButtons.YesNo);
            if (dr == DialogResult.Yes)
            {
                m_ModBusTestStep = cvs.MODBUS.STEP_IDLE;
                vmModbusTcpMaster1.Set(1, "Reset000", "0");

                ResetScanningTextBox();
                EnableScanningTextBox(true);

                isMachineWorking = false;
                uiLabelConfig.Text = string.Empty;
                strBarcodeA1 = "";
                strBarcodeA2 = "";
                strBarcodeA3 = "";
                MachineStatusA = 0;
                MachineStatusB = 0;
                bTabAworking = false;
                bTabBworking = false;
                uiLabelInfo.Text = "等待扫描条码......";
                uiLabelInfo.BackColor = Color.White;
            }
        }
        private void btnExitApplication_Click(object sender, EventArgs e)
        {
            btnSaveSysConf_Click(null, null);
            vmTcpIpUcom.Stop();
            vmTcpPrinter.Stop();
            vmModbusTcpMaster1.Stop();

            confirmResultTimer.Stop();
            mainTimer.Stop();
            this.Close();
        }
        int centerPanelPositionY = 122;

        private void button3_Click(object sender, EventArgs e)
        {
            if (access_right == (int)cvs.AccessRight.Operator)
            {
                int ar = 0;
                login lgn = new login();
                lgn.ShowDialog();
                if (lgn.DialogResult == DialogResult.OK)
                {
                    ar = lgn.access_right;
                    if (ar == (int)cvs.AccessRight.Operator)
                    {
                        MessageBox.Show("用户没有权限", "权限不足", MessageBoxButtons.OK);
                        return;
                    }
                }
                else
                    return;
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            //弹出录入密码窗口
            isSysteConfigLoginShowing = true;

            SystemConfigLogin systemConfigLogin = new SystemConfigLogin(SystemConfigPwd);

            systemConfigLogin.ShowDialog();

            isSysteConfigLoginShowing = false;

            if (systemConfigLogin.DialogResult != DialogResult.OK) return;

        }

        bool isSysteConfigLoginShowing = false;

        //是否正在显示报警窗口
        bool isWarningMessageShowing = false;
        //bool isAlarmOn = false;
        private void DisplayWarningInformation(string warningInformation, Color backColor)
        {
            DisplayInformation(warningInformation, backColor);
            //设置报警窗口打开标志
            isWarningMessageShowing = true;
            isWarningOn = false;
            WarningMessageBox warningMessageBox = new WarningMessageBox(warningInformation);
            warningMessageBox.ShowDialog();

            isWarningMessageShowing = false;
        }
        private void DisplayInformation(string information, Color backColor)
        {
            int cnt = 1;
            uiLabelInfo.Text = information;
            uiLabelInfo.BackColor = backColor;
            if (backColor == Color.Red) cnt = -1;

            string warningInformationSave = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + information;
            string warningInformationTime = DateTime.Now.ToString("HH:mm:ss ") + information;
            uiDataGridViewLog.Rows.Insert(0, warningInformationTime);
            SaveLogToFile(device_name, warningInformationSave, cnt);
        }

        //单工位一条码
        private string HandleBarcode4(string str)
        {
            if (str == strOKA || str == strNGA || str == strCancelA)
            {
                if (!bTabAworking)
                {
                    if (strBarcodeA2 == "")
                        DisplayWarningInformation("加工还没有开始，请扫描类型条码", Color.Red);
                    else
                        DisplayWarningInformation("加工还没有开始，请扫描个骨架条码", Color.Red);
                    return "";
                }
            }
            if (str == strOKA)
            {
                strSerialNumA = DateTime.Now.ToString("HHmmss");
                string strBarcode = strBarcodeA1;  //骨架条码
                strBarcodeA1 = "";  //产品类型条码
                strBarcodeA2 = "";
                //lblConfig.Text = "";
                //lblBarcodeA1.Text = "";

                EndTimeA = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                MachineStatusA = 1;
                WaitingTimeA = 0;
                return "CHECKOUT," + strSerialNumA + "," + device_name + "," + strBarcode
                    + ",1," + user_id + "," + StartTimeA + ";" + EndTimeA + ",," + strBarcodeA2;
            }
            if (str == strNGA)
            {
                strSerialNumA = DateTime.Now.ToString("HHmmss");
                string strBarcode = strBarcodeA1;  //骨架条码
                strBarcodeA1 = "";  //产品类型条码
                strBarcodeA2 = "";
                //lblBarcodeA1.Text = "";
                //lblConfig.Text = "";
                EndTimeA = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                MachineStatusA = 1;
                WaitingTimeA = 0;
                return "CHECKOUT," + strSerialNumA + "," + device_name + "," + strBarcode
                    + ",2," + user_id + "," + StartTimeA + ";" + EndTimeA + ",," + strBarcodeA2;
            }
            if (str == strRepairA)
            {
                strSerialNumA = DateTime.Now.ToString("HHmmss");
                string strBarcode = strBarcodeA1;  //骨架条码
                strBarcodeA1 = "";  //产品类型条码
                strBarcodeA2 = "";
                //lblBarcodeA1.Text = "";
                //lblConfig.Text = "";
                EndTimeA = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                MachineStatusA = 1;
                WaitingTimeA = 0;
                return "CHECKOUT," + strSerialNumA + "," + device_name + "," + strBarcode
                    + ",3," + user_id + "," + StartTimeA + ";" + EndTimeA + ",," + strBarcodeA2;
            }
            if (str == strCancelA)
            {
                bTabAworking = false;
                MachineStatusA = 0;
                strBarcodeA1 = "";
                strBarcodeA2 = "";
                //lblBarcodeA1.Text = "";
                //lblConfig.Text = "";
                DisplayInformation(strBarcodeA1 + " 加工取消，请扫描骨架条码", Color.LightGreen);
                if (confirmResult != null)
                {
                    confirmResult.Close();
                    InitConfirmResultStatus();
                }
                return "";
            }
            //如果确认加工结果窗口打开就退出
            if (isConfirmResultShowing) return "";

            if (!bTabAworking)
            {
                if (strBarcodeA2 == "") //产品类型还没有扫描
                {
                    //lblBarcodeA1.Text = "";
                    //lblConfig.Text = "";
                    strBarcodeA2 = str;
                    //lblConfig.Text = strBarcodeA2;
                    DisplayInformation("请扫描骨架条码", Color.LightGreen);
                    return "";
                }
                else if (strBarcodeA1 == "")    //骨架条码还没有扫描
                {
                    MachineStatusA = 1;
                    WaitingTimeA = 0;
                    strBarcodeA1 = str;
                    //lblBarcodeA1.Text = str;
                    strSerialNumA = DateTime.Now.ToString("HHmmss");
                    StartTimeA = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    return "CHECKIN," + strSerialNumA + "," + device_name + "," + strBarcodeA1 + ",," + strBarcodeA2;
                }
            }
            //扫描的条码非OK/NG/Cancel
            if (MachineStatusA == 2)
            {
                DisplayWarningInformation(strBarcodeA1 + " 正在加工，请扫描加工结果条码", Color.Red);
                return "";
            }
            return strStationWorking;
        }
        private void HandlePrint(string str)
        {
            //正在加工？已经扫描了足够的物料条码，正在与UCOM通讯，然后打印。
            if (isMachineWorking)
            {
                DisplayInformation("正在打印，请等待......", Color.Red);
                return;
            }

            string _strSendToUcom = string.Empty;

            if (isMachineWorking)
            {
                //if (cbbProductConfig.SelectedItem != null)
                {
                    _strSendToUcom = "VALIDATEBOM," + DateTime.Now.ToString("HHmmss") + "," + device_name + ",";
                    _strSendToUcom += user_id + ",";
                    //_strSendToUcom += cbbProductConfig.SelectedItem.ToString().Split('/')[0] + ",";
                    _strSendToUcom += "MATERIAL1:" + strBarcodeA1 + ";" + "MATERIAL2:" + strBarcodeA2 + ";";
                    _strSendToUcom += "MATERIAL3:" + strBarcodeA3;
                    vmTcpIpUcom.Set(_strSendToUcom);

                    if (confirmResult != null)
                    {
                        confirmResult.Close();
                        InitConfirmResultStatus();
                    }
                }
            }
        }

        private void CheckLogTime()
        {
            DateTime dt8 = ShiftStartTime;
            DateTime dt8UP = dt8.AddSeconds(10);
            DateTime dt20 = ShiftStartTime.AddHours(12);
            DateTime dt20UP = dt20.AddSeconds(10);
            if ((DateTime.Now >= dt8 && DateTime.Now <= dt8UP) || (DateTime.Now >= dt20 && DateTime.Now < dt20UP))
            {
                this.Hide();
                if (!bLoginForm)
                {
                    try
                    {
                        lgn.ShowDialog();
                        bLoginForm = true;
                    }
                    catch
                    { }

                    if (lgn.DialogResult == DialogResult.OK)
                    {
                        bLoginForm = false;
                        this.Show();
                    }

                    else if (lgn.DialogResult == DialogResult.Cancel)
                    {
                        vmTcpIpUcom.Stop();
                        this.Close();
                        //Application.Exit();
                    }
                }
            }
        }

        private void btnSaveConfig_Click(object sender, EventArgs e)
        {
            xmlHelper.WriteXml(cvs.DP.SYSTEM_CONFIG_FILE, "DEVICE_CODE", tbDeviceName.Text);
            xmlHelper.WriteXml(cvs.DP.SYSTEM_CONFIG_FILE, "SCAN_BY_ORDER",
                uiCheckBoxScanOrder.Checked ? "1" : "0");

            device_name = tbDeviceName.Text;
            vmTcpIpUcom.SaveSettings();
            vmTcpPrinter.SaveSettings();
            vmModbusTcpMaster1.SaveSettings();

            InitDevice();
        }
        private void ShowProductQuantity(List<ProductionDataClass> productionDatas)
        {
            int reportYield = 0;        //报产数量

            //显示计划数量
            tbPlanQuantity.Text = planQty.ToString();

            ////显示合格数量
            //tbOKQuantity.Text = okQuantity.ToString();

            ////不合格数量
            //tbNGQuantity.Text = ngQuantity.ToString();

            ////返修数量
            //tbREQuantity.Text = reQuantity.ToString();

            ////合计数量
            //tbSumQuantity.Text = (okQuantity + ngQuantity + reQuantity).ToString();

            uiDataGridViewProduction.Rows.Clear();
            foreach (ProductionDataClass pd in productionDatas)
            {
                string[] _lvi = new string[] {
                pd.config,pd.okQty.ToString(),pd.ngQty.ToString(),pd.finishedQty.ToString()
                };
                uiDataGridViewProduction.AddRow(_lvi);
                reportYield += pd.reportYield;
            }
            int _total = productionDatas.Sum(p => p.finishedQty);
            tbSumQuantity.Text = _total.ToString();
            //报产数量
        }

        bool toOpenConfirmResult = false;

        private void confirmResultTimer_Tick(object sender, EventArgs e)
        {
            if (!toOpenConfirmResult) return;
            //已经打开了窗口就不执行
            if (isConfirmResultShowing)
            {
                toOpenConfirmResult = false;
                return;
            }
            //打开confirmResult窗口
            toOpenConfirmResult = false;
            isConfirmResultShowing = true;
            confirmResult = new ConfirmResult();
            confirmResult.ShowDialog();

            string choice = string.Empty;

            switch (confirmResult.DialogResult)
            {
                case DialogResult.OK:
                    choice = strOKA;
                    //vmTcpIpUcom.Set(HandleBarcode4(strOKA));
                    break;
                case DialogResult.No:
                    choice = strNGA;
                    //vmTcpIpUcom.Set(HandleBarcode4(strNGA));
                    break;
                case DialogResult.Ignore:
                    choice = strCancelA;
                    //HandleBarcode4(strCancelA);
                    break;
                case DialogResult.Yes:
                    choice = strRepairA;
                    //vmTcpIpUcom.Set(HandleBarcode4(strRepairA));
                    break;
            }

            ToCheckout(choice);

            //返回到初始化的状态
            InitConfirmResultStatus();
        }

        private void ToCheckout(string choice)
        {
            int result = 1;

            if (choice == strCancelA)
            {
                // Show information and clear desktop
                DisplayInformation("加工取消", Color.LightGreen);
                uiLabelConfig.Text = string.Empty;
                MachineStatusA = 0;
                return;
            }
            switch (choice)
            {
                case strOKA:
                    result = 1;
                    break;
                case strNGA:
                    result = 2;
                    break;
                case strRepairA:
                    result = 3;
                    break;

            }

            Checkout(result);
        }

        private void Checkout(int result)
        {
            CheckOutDataClass checkoutData = new CheckOutDataClass();
            checkoutData.cmd = "CHECKOUT";
            m_serialNo = DateTime.Now.ToString("HHmmss");
            checkoutData.cmdTime = m_serialNo;
            checkoutData.deviceId = device_name;
            checkoutData.userId = user_id;
            checkoutData.barcode = m_strBarcode;
            checkoutData.startTime = m_startTimeA;
            checkoutData.endTime = DateTime.Now.ToString();
            checkoutData.workOrder = uiLabelConfig.Text;
            checkoutData.result = result;
            checkoutData.config = m_config;
            checkoutData.bPrintCustomerBarcode = toCreateCustomerBarcode == 1 ? true : false;
            checkoutData.productConfigs = m_productConfigWithItemContent;
            //.Where(p => p.traceabilityKey != 1)
            //.ToList();
            checkoutData.reportYieldType =
                m_device.DeviceInfomation.ReportYieldStatus;

            vmTcpIpUcom.Set(JsonConvert.SerializeObject(checkoutData, Formatting.Indented));

        }

        private void InitConfirmResultStatus()
        {
            isConfirmResultShowing = false;
        }
        string alarmParameterString = "alarm";
        string alarmString;
        string alarmReset = "0,0,1,0";
        string[] alarmLoop;
        bool isAlarmLoopWorking = false;
        bool isWarningOn = false;
        int alarmIdx = 0;
        int alarmLoopCounter = 600;
        bool isAlarmReset = true;

        private void ReprintPls(string str)
        {
            vmTcpIpUcom.Set("REPRINTPLS," + DateTime.Now.ToString("HHmmss") + "," + device_name + "," + str);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            return;

            //如果设备处于停机状态，就报警然后退出
            if (m_device.DeviceInfomation.DeviceState != cvs.DEVICE_STATE.NORMAL)
            {
                DisplayInformation("设备处于停机状态，请取消停机。", Color.Red);
                return;
            }
            string strTcpIpSend = string.Empty;
            //strTcpIpSend = HandleBarcode4(strScanner);
            HandlePrint(strPrint);
            if (strTcpIpSend == "")
            {
                DisplayWarningInformation("未选择配置，请扫描配置条码", Color.Red);
                return;
            }
            else if (strTcpIpSend == strStationWorking)
            {
                DisplayWarningInformation(strBarcodeA1 + " 正在加工", Color.Red);
                return;
            }
            else
            {
                string[] strs1 = strTcpIpSend.Split(',');
                string[] strs2 = strs1[3].Split(';');
                vmTcpIpUcom.Set(strTcpIpSend);
                if (confirmResult != null)
                {
                    confirmResult.Close();
                    InitConfirmResultStatus();
                }
            }
        }


        /// <summary>
        /// 打印客户条码使用实例来传递数据
        /// </summary>
        public class PrintBarcodeData
        {
            public string barcode;             //要打印的客户条码
            public string ICA2CfgChn;          //ICA2配置信息，中文，如：黑加红缝线

            public string date;
            public string config;               // HA5H-5305030
            public string configPrefix;         // HA5H
            public string vendorCode;           // 153390
            public string flow;                 // 2403280001
            public string name;                 // 副仪表盘后安装支架总成
        }

        private void btnSuspendOrRestoreDevice_Click(object sender, EventArgs e)
        {
            switch (m_device.DeviceInfomation.DeviceState)
            {
                case cvs.DEVICE_STATE.NORMAL:
                    SuspendDevice();
                    break;
                case cvs.DEVICE_STATE.SUSPENDED:
                    RestoreDevice();
                    break;
            }
        }
        private void SuspendDevice()
        {
            //向UCOM发送停机指令
            SuspendReason suspendReason = new SuspendReason(m_suspendReasons);
            DialogResult dialogResult = suspendReason.ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                DeviceInfomation deviceInfomation = new DeviceInfomation();
                deviceInfomation.DeviceId = this.device_name;
                Device device = new Device(deviceInfomation);
                string _cmd = device.DeviceCommand(cvs.DEVICE_COMMAND.TO_SUSPEND_DEVICE, suspendReason.reason);
                vmTcpIpUcom.Set(_cmd);
            }
        }
        private void RestoreDevice()
        {
            //向UCOM发送停机指令
            DeviceInfomation deviceInfomation = new DeviceInfomation();
            deviceInfomation.DeviceId = this.device_name;
            Device device = new Device(deviceInfomation);
            string _cmd = device.DeviceCommand(cvs.DEVICE_COMMAND.BACK_TO_NORMAL, string.Empty);
            vmTcpIpUcom.Set(_cmd);
        }
        private void InitDevice()
        {
            DeviceInfomation deviceInfomation = new DeviceInfomation();
            deviceInfomation.DeviceId = device_name;
            m_device = new Device(deviceInfomation);
            //string _cmd = m_device.DeviceCommand(cvs.DEVICE_COMMAND.GET_DEVICE_STATE, string.Empty);
            //vmTcpIpUcom.Set(_cmd);

            DeviceDataClass deviceData = new DeviceDataClass();
            deviceData.cmd = "DEVICE";
            m_serialNo = DateTime.Now.ToString("HHmmss");
            deviceData.cmdTime = m_serialNo;
            deviceData.deviceId = device_name;
            deviceData.userId = user_id;
            deviceData.deviceCommand = cvs.DEVICE_COMMAND.GET_DEVICE_STATE;
            vmTcpIpUcom.Set(JsonConvert.SerializeObject(deviceData, Formatting.Indented));
        }
        private void HandleDevice(string response)
        {
            DeviceController controller = new DeviceController(response);

            if (controller.DeviceResponse.status == "NOK")
            {
                DisplayInformation(controller.DeviceResponse.message, Color.Red);
                return;
            }

            switch (controller.DeviceResponse.state)
            {
                case cvs.DEVICE_STATE.NORMAL:
                    m_device.DeviceInfomation.DeviceState = cvs.DEVICE_STATE.NORMAL;
                    //改变按钮颜色和显示内容
                    btnSuspendOrRestoreDevice.BackColor = Color.LightGreen;
                    btnSuspendOrRestoreDevice.Text = "停机";
                    break;
                case cvs.DEVICE_STATE.SUSPENDED:
                    m_device.DeviceInfomation.DeviceState = cvs.DEVICE_STATE.SUSPENDED;
                    //改变按钮颜色和显示内容
                    btnSuspendOrRestoreDevice.BackColor = Color.Yellow;
                    btnSuspendOrRestoreDevice.Text = "取消停机";
                    break;
            }
            m_suspendReasons = controller.DeviceResponse.reasons.Select(r => r.reason).ToArray();
            m_suspendSolutions = controller.DeviceResponse.solutions.Select(s => s.solution).ToArray();

            switch (controller.DeviceResponse.reportYieldType)
            {
                case cvs.REPORT_YIELD_TYPE.AUTO:
                    btnAutoReport.BackColor = Color.LightGreen;
                    btnAutoReport.Text = "自动报产开启中";
                    break;
                case cvs.REPORT_YIELD_TYPE.MANUAL:
                    btnAutoReport.BackColor = Color.Yellow;
                    btnAutoReport.Text = "自动报产关闭中";
                    break;
            }
            m_device.DeviceInfomation.ReportYieldStatus = controller.DeviceResponse.reportYieldType;

            cbType.DataSource = controller.DeviceResponse.configs;

        }
        private void HandleDevice(string[] strs)
        {
            //UCOM发聩信息：DEVICE,流水,DEVICEID,COMMAND,STATE(0-NORMAL,11-SUSPENDED),SUSPENDREASIONS,SUSPENDSOLUTIONS,
            // REPORT YIELD TYPE

            if (strs.Length < 8) return;

            bool _v;
            int _state;
            _v = int.TryParse(strs[4], out _state);

            if (_v)
            {

                switch (_state)
                {
                    case cvs.DEVICE_STATE.NORMAL:
                        m_device.DeviceInfomation.DeviceState = cvs.DEVICE_STATE.NORMAL;
                        //改变按钮颜色和显示内容
                        btnSuspendOrRestoreDevice.BackColor = Color.LightGreen;
                        btnSuspendOrRestoreDevice.Text = "停机";
                        break;
                    case cvs.DEVICE_STATE.SUSPENDED:
                        m_device.DeviceInfomation.DeviceState = cvs.DEVICE_STATE.SUSPENDED;
                        //改变按钮颜色和显示内容
                        btnSuspendOrRestoreDevice.BackColor = Color.Yellow;
                        btnSuspendOrRestoreDevice.Text = "取消停机";
                        break;
                }
                m_suspendReasons = strs[5].Split(';');
                m_suspendSolutions = strs[6].Split(';');
            }

            //报产方式
            bool vrf = false;
            int reportYieldType = 0;
            vrf = int.TryParse(strs[7], out reportYieldType);

            if (vrf)
            {
                switch (reportYieldType)
                {
                    case cvs.REPORT_YIELD_TYPE.AUTO:
                        btnAutoReport.BackColor = Color.LightGreen;
                        btnAutoReport.Text = "自动报产开启中";
                        break;
                    case cvs.REPORT_YIELD_TYPE.MANUAL:
                        btnAutoReport.BackColor = Color.Yellow;
                        btnAutoReport.Text = "自动报产关闭中";
                        break;
                }
                m_device.DeviceInfomation.ReportYieldStatus = reportYieldType;
            }
        }

        bool isSystemConfigLoginShowing = false;

        private string bypassConfigPwd;
        private int m_matListOnConfigCount;
        private List<ProductConfigWithItemContent> m_productConfigWithItemContent;
        private string m_config;
        private string m_serialNo;
        private int toCreateCustomerBarcode;
        private string m_startTimeA;            //加工开始时间
        private bool m_bBypassPlc;

        public string BypassConfigPwd { get => bypassConfigPwd; set => bypassConfigPwd = value; }
        private void btnAutoReport_Click(object sender, EventArgs e)
        {
            //弹出录入密码窗口
            isSystemConfigLoginShowing = true;

            SystemConfigLogin systemConfigLogin = new SystemConfigLogin(BypassConfigPwd);

            systemConfigLogin.ShowDialog();

            isSystemConfigLoginShowing = false;

            if (systemConfigLogin.DialogResult != DialogResult.OK) return;

            int cmd = -1;
            switch (m_device.DeviceInfomation.ReportYieldStatus)
            {
                case cvs.REPORT_YIELD_TYPE.AUTO:
                    cmd = cvs.DEVICE_COMMAND.REPORT_YIELD_SWITCH_TO_MANUAL;
                    break;
                case cvs.REPORT_YIELD_TYPE.MANUAL:
                    cmd = cvs.DEVICE_COMMAND.REPORT_YIELD_SWITCH_TO_AUTO;
                    break;
            }
            if (cmd == -1) return;

            DeviceInfomation deviceInfomation = new DeviceInfomation();
            deviceInfomation.DeviceId = this.device_name;
            Device device = new Device(deviceInfomation);
            string _cmd = device.DeviceCommand(cmd, "");
            vmTcpIpUcom.Set(_cmd);

        }
        /// <summary>
        /// 扫描配置条码，并且回车，那么就将光标跳到扶手输入框
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void uiTextBoxScan_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                if (MachineStatusA != 0)    //正在加工中，或者等待服务器回复
                {
                    DisplayInformation("正在加工，请等候加工完成", Color.Red);
                    return;
                }

                string scanString = uiTextBoxScan.Text.Trim();

                // 还没有执行 GetWorkOrder, 没有获取零件列表，就发送 GetWorkOrder 命令到服务器
                if (uiLabelConfig.Text == string.Empty)
                {
                    uiLabelConfig.Text = scanString;
                    uiDataGridViewSparePart.Rows.Clear();
                    uiDataGridViewSparePart.BackgroundColor = Color.White;

                    GetWorkOrder(scanString);
                    return;
                }

                // 已经获取了零件列表
                if (m_productConfigWithItemContent == null)
                {
                    DisplayInformation("没有物料信息", Color.Red);
                    return;
                }

                //if (m_isMatListOnConfigReceived)    // 收到UCOM发回的物料列表
                foreach (var item in m_productConfigWithItemContent)
                {
                    if (item.scan == "")
                    {
                        if (scanString.Contains(item.content))
                        {
                            int idx = m_productConfigWithItemContent.IndexOf(item);
                            uiTextBoxScan.Text = string.Empty;
                            FillDataGridViewToCheckin(idx, scanString);
                            return;
                        }
                        else
                        {
                            if (uiCheckBoxScanOrder.Checked)
                            {
                                DisplayInformation("扫描的物料: " + scanString + " 与所需物料不匹配", Color.Red);
                                return;
                            }
                        }
                    }
                }
                DisplayInformation("扫描的物料: " + scanString + " 与所需物料不匹配", Color.Red);
                return;
            }
        }

        /// <summary>
        /// 填充 零件列表，如果能够全部填充，那么就可以checkin
        /// </summary>
        /// <param name="idx"></param>
        /// <param name="str"></param>
        private void FillDataGridViewToCheckin(int idx, string str)
        {

            if (m_productConfigWithItemContent[idx].traceabilityKey == 1) m_strBarcode = str;       // 骨架条码赋值

            m_productConfigWithItemContent[idx].scan = str;
            uiDataGridViewSparePart.Rows[idx].Cells["scan"].Value = str;
            uiDataGridViewSparePart.Rows[idx].Cells["scan"].Style.BackColor = Color.LightGreen;

            m_serialNo = DateTime.Now.ToString("HHmmss");

            bool allFilled = true;
            for (int i = 0; i < m_productConfigWithItemContent.Count; i++)
            {
                if (m_productConfigWithItemContent[i].scan == string.Empty)
                {
                    allFilled = false;
                    break;
                }
            }
            if (allFilled)
            {
                CheckInDataClass checkInData = new CheckInDataClass();
                checkInData.cmd = "CHECKIN";
                checkInData.cmdTime = m_serialNo;
                checkInData.deviceId = device_name;
                checkInData.userId = user_id;
                checkInData.Barcode = m_strBarcode;
                checkInData.Config = m_config;
                checkInData.WorkOrder = uiLabelConfig.Text;
                checkInData.ProductConfigs = m_productConfigWithItemContent;


                DisplayInformation("正在 Checkin...", Color.LightGreen);

                MachineStatusA = 1; //等待回复
                vmTcpIpUcom.Set(JsonConvert.SerializeObject(checkInData, Formatting.Indented));
            }
            else
            {
                DisplayInformation("请扫描物料条码", Color.LightGreen);
                return;
            }
        }
        private void GetWorkOrder(string scanString)
        {
            DisplayInformation("正在获取零件列表...", Color.LightGreen);

            WorkOrderDataClass workOrder = new WorkOrderDataClass();
            workOrder.cmd = "GetWorkOrder";
            workOrder.cmdTime = DateTime.Now.ToString("HHmmss");
            workOrder.deviceId = device_name;
            workOrder.userId = user_id;
            workOrder.workOrder = scanString;

            vmTcpIpUcom.Set(JsonConvert.SerializeObject(workOrder, Formatting.Indented));
        }

        private void StartOperation()
        {
            //if (uiTextBoxScan.Text.Trim() == ""
            //    || uiTextBoxArm.Text.Trim() == ""
            //    || uiTextBoxWire.Text.Trim() == "")
            {
                DisplayInformation("扫描信息不能为空。", Color.Red);
                return;
            }

            //如果设备处于停机状态，就报警然后退出
            if (m_device.DeviceInfomation.DeviceState != cvs.DEVICE_STATE.NORMAL)
            {
                DisplayInformation("设备处于停机状态，请取消停机。", Color.Red);
                return;
            }

            if (m_ModBusTestStep != cvs.MODBUS.STEP_IDLE)
            {
                DisplayInformation("检测状态非空闲，请等待或者初始化", Color.Red);
                return;
            }

            EnableScanningTextBox(false);

            string _strSendToUcom = "VALIDATE_ELECTEST," + DateTime.Now.ToString("HHmmss") + "," + device_name + ",";
            _strSendToUcom += user_id + ",";
            _strSendToUcom += uiTextBoxScan.Text + ",";
            //        _strSendToUcom += "MATERIAL1:" + uiTextBoxArm.Text + ";" + "MATERIAL2:" + uiTextBoxWire.Text;
            vmTcpIpUcom.Set(_strSendToUcom);
        }

        private void mainForm_Shown(object sender, EventArgs e)
        {
            uiTextBoxScan.Focus();

        }
        /// <summary>
        /// 打开/关闭 扫描输入框
        /// </summary>
        /// <param name="flag">
        /// true : enable
        /// false : disable
        /// </param>
        private void EnableScanningTextBox(bool flag)
        {
            uiTextBoxScan.Enabled = flag;
            //uiTextBoxArm.Enabled = flag;
            //uiTextBoxWire.Enabled = flag;
        }
        private void ResetScanningTextBox()
        {
            uiTextBoxScan.Text = "";
            //uiTextBoxArm.Text = "";
            //uiTextBoxWire.Text = "";
            uiTextBoxScan.Focus();
        }

        private void uiButtonStartOperation_Click(object sender, EventArgs e)
        {
            StartOperation();
        }

        private void btnBypassPlc_Click(object sender, EventArgs e)
        {
            //弹出录入密码窗口
            isSystemConfigLoginShowing = true;

            SystemConfigLogin systemConfigLogin = new SystemConfigLogin(BypassConfigPwd);

            systemConfigLogin.ShowDialog();

            isSystemConfigLoginShowing = false;

            if (systemConfigLogin.DialogResult != DialogResult.OK) return;

            m_bBypassPlc = !m_bBypassPlc;

            if (m_bBypassPlc)
            {
                btnBypassPlc.BackColor = Color.Yellow;
                btnBypassPlc.Text = "连接设备";
            }
            else
            {
                btnBypassPlc.BackColor = Color.LightGreen;
                btnBypassPlc.Text = "设备通讯";
            }
            xmlHelper.WriteXml(cvs.DP.SYSTEM_CONFIG_FILE, "BYPASS", m_bBypassPlc.ToString());

        }

        private void mainForm_Load(object sender, EventArgs e)
        {
            uiDataGridViewLog.Columns[0].Width = uiDataGridViewLog.Width - 3;
        }

        private void btnPrintOldBarcode_Click(object sender, EventArgs e)
        {
            ReprintBarcode(tbPrintOldBaarcode.Text);

        }
        private void ReprintBarcode(string str)
        {
            ReprintBarcodeDataClass data = new ReprintBarcodeDataClass();
            data.cmd = "REPRINT_BARCODE";
            m_serialNo = DateTime.Now.ToString("HHmmss");
            data.cmdTime = m_serialNo;
            data.deviceId = device_name;
            data.userId = user_id;
            data.barcode = str;

            vmTcpIpUcom.Set(JsonConvert.SerializeObject(data, Formatting.Indented));
        }

        private void btnPrintM_Click(object sender, EventArgs e)
        {
            PrintMDataClass data = new PrintMDataClass();
            data.cmd = "PRINT_M";
            m_serialNo = DateTime.Now.ToString("HHmmss");
            data.cmdTime = m_serialNo;
            data.deviceId = device_name;
            data.userId = user_id;
            data.config = cbType.SelectedValue.ToString();
            data.date = dtpPrint.Value;
            data.quantity = (int)nudPrintQuantity.Value;
            data.reportYieldType =
                m_device.DeviceInfomation.ReportYieldStatus;

            vmTcpIpUcom.Set(JsonConvert.SerializeObject(data, Formatting.Indented));
        }

        private void uiTabControlMain_SelectedIndexChanged(object sender, EventArgs e)
        {


        }

        private void uiTabControlMain_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (uiTabControlMain.SelectedIndex == 0)
            {

                return;
            }
            //弹出录入密码窗口
            isSystemConfigLoginShowing = true;

            SystemConfigLogin systemConfigLogin = new SystemConfigLogin(BypassConfigPwd);

            systemConfigLogin.ShowDialog();

            isSystemConfigLoginShowing = false;

            if (systemConfigLogin.DialogResult != DialogResult.OK)
            {
                e.Cancel = true;
                return;
            }
        }
    }
}

